package com.example.gustavo.hello.activity;


import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.Movie;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.CycleInterpolator;
import android.webkit.MimeTypeMap;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.avos.avoscloud.AVObject;
import com.example.gustavo.hello.MyApplication;
import com.example.gustavo.hello.R;
import com.example.gustavo.hello.model.HelloObj;
import com.example.gustavo.hello.net.OkHttpStack;
import com.example.gustavo.hello.net.OkHttpUrlStack;
import com.example.gustavo.hello.net.RetrofitService;
import com.example.gustavo.hello.utils.StreamUtil;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.FileAsyncHttpResponseHandler;
import com.loopj.android.http.SyncHttpClient;
import com.loopj.android.http.TextHttpResponseHandler;
import com.orhanobut.logger.Logger;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;

import org.apache.http.Header;
import org.apache.http.client.methods.HttpHead;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.OctJwkGenerator;
import org.jose4j.jwk.OctetSequenceJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.HmacUsingShaAlgorithm;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import org.jose4j.keys.AesKey;
import org.jose4j.keys.HmacKey;
import org.jose4j.lang.ByteUtil;
import org.jose4j.lang.JoseException;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.sql.Date;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
import retrofit.RestAdapter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class RxJavaActivity extends Activity {


    private static final String TAG = "RxJavaActivity";
    private TextView tv;
    private Button btn;
    private String url = "http://www.baidu.com";
    private String textUrl = "http://p.gdown.baidu.com/3e0fbab1aa0f2af808019fd6887d149405eec0875bccc0c53a74875e5f402e49f0cc90adfad4c8a7f5534aee08a1bdccfd36fbb025fc1c3a5c64b76c0f5a5d1e0c648e8b3fc9bb47d77263c1ce2a0d9c85e372c65288c8e66cb97484ecee3202643a8b465fcbe1130944ae6aec2cb52185c392a40b42eff12b4efeb60b457d44423e64ca47871fcce80852b3a511ec2178b8ad0133d5687c23d55b5420ffbeb907dfcb4d2f7f0226b6d6c9f1c3575205ec63632fc03886d72093102d7e6c0d3ef28e5dcda96a2e6068d09d2662716522801a4718d5b10d5eaedc208e191f5576b534aed8ff247c7af7d8e1fde7d5a68c115e8f0dd2a7905983e2553af65cbab68d2b125346a61b30795e6bb74e84d991";
    private int count;
    private boolean isFirst = true;
    private ImageView imageView;
    private Observable.Transformer transformer = new Observable.Transformer() {
        @Override
        public Observable call(Object observable) {
            return ((Observable)observable)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_rx_java);
        Logger.init(TAG).setMethodCount(0).hideThreadInfo();

        tv = (TextView) findViewById(R.id.tv);
        btn = (Button) findViewById(R.id.btn);
        imageView = (ImageView) findViewById(R.id.imageView3);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

//                retrofitHttp();

                try {
//                    okHttp();
                    testJWT();
                } catch (Exception e) {
                    e.printStackTrace();
                }


            }
        });

    }
    //JWT TEST
    public void testJWT() throws Exception {
        String secret = "weisd";

        HmacKey hmacKey = new HmacKey(secret.getBytes("UTF-8"));

        // Create the Claims, which will be the content of the JWT
        JwtClaims claims = new JwtClaims();
        claims.setIssuer("Issuer");  // who creates the token and signs it
        claims.setAudience("Audience"); // to whom the token is intended to be sent
        claims.setExpirationTimeMinutesInTheFuture(5); // time when the token will expire (10 minutes from now)
//        claims.setExpirationTime(NumericDate.fromMilliseconds(System.currentTimeMillis() + 1000 * 30));
        claims.setGeneratedJwtId(); // a unique identifier for the token
        claims.setIssuedAtToNow();  // when the token was issued/created (now)
        claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
        claims.setSubject("subject"); // the subject/principal is whom the token is about
        claims.setClaim("email", "mail@example.com"); // additional claims/attributes about the subject can be added
        List<String> groups = Arrays.asList("group-one", "other-group", "group-three");
        claims.setStringListClaim("groups", groups); // multi-valued claims work too and will end up as a JSON array

        // A JWT is a JWS and/or a JWE with JSON claims as the payload.
        // In this example it is a JWS so we create a JsonWebSignature object.
        JsonWebSignature jws = new JsonWebSignature();

        // The payload of the JWS is JSON content of the JWT Claims
        String json = claims.toJson();
        Log.w(TAG, "json = " + json);
        jws.setPayload(json);

        // The JWT is signed using the private key
        jws.setKey(hmacKey);

        // Set the Key ID (kid) header because it's just the polite thing to do.
        // We only have one key in this example but a using a Key ID helps
        // facilitate a smooth key rollover process
//        jws.setKeyIdHeaderValue(hmacKey.getKeyId());

        // Set the signature algorithm on the JWT/JWS that will integrity protect the claims
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setDoKeyValidation(false);//不校验key 例如长度

        // Sign the JWS and produce the compact serialization or the complete JWT/JWS
        // representation, which is a string consisting of three dot ('.') separated
        // base64url-encoded parts in the form Header.Payload.Signature
        // If you wanted to encrypt it, you can simply set this jwt as the payload
        // of a JsonWebEncryption object and set the cty (Content Type) header to "jwt".
        String jwt = jws.getCompactSerialization();


        // Now you can do something with the JWT. Like send it to some other party
        // over the clouds and through the interwebs.
        Log.w(TAG, "JWT: " + jwt);

        AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
        asyncHttpClient.addHeader("Authorization", "Bearer " + jwt);
        asyncHttpClient.addHeader("client-id", "da");


        asyncHttpClient.get("http://192.168.0.33:1323/jwt/info", new TextHttpResponseHandler() {

            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {

            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, String responseString) {

                Log.w(TAG, "result= " + responseString);
            }
        });

    }

    private void volley(){

        //Volley 使用 OkHttpClient
//        RequestQueue requestQueue = Volley.newRequestQueue(this, new OkHttpUrlStack());
        RequestQueue requestQueue = Volley.newRequestQueue(this, new OkHttpStack(new OkHttpClient()));
        StringRequest stringRequest = new StringRequest(url, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Log.i(TAG, "response=" + s);

            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {

            }
        });
        requestQueue.add(stringRequest);
    }

    private void okHttp() throws IOException {


        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();

        //进度
        final ProgressListener progressListener = new ProgressListener() {
            @Override
            public void update(long bytesRead, long contentLength, boolean done) {

                Logger.d(bytesRead + "/" + contentLength + " = " + (bytesRead * 100f / contentLength) + "% " + done);
            }
        };

        okHttpClient.networkInterceptors().add(new Interceptor() {
            @Override public Response intercept(Chain chain) throws IOException {
                Response originalResponse = chain.proceed(chain.request());
                return originalResponse.newBuilder()
                        .body(new ProgressResponseBody(originalResponse.body(), progressListener))
                        .build();
            }
        });

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {

            }

            @Override
            public void onResponse(Response response) throws IOException {


                Logger.d(response.body().string().substring(0, 100));

            }
        });

    }

    interface ProgressListener {
        void update(long bytesRead, long contentLength, boolean done);
    }
    private static class ProgressResponseBody extends ResponseBody {

        private final ResponseBody responseBody;
        private final ProgressListener progressListener;
        private BufferedSource bufferedSource;

        public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
            this.responseBody = responseBody;
            this.progressListener = progressListener;
        }

        @Override public MediaType contentType() {
            return responseBody.contentType();
        }

        @Override public long contentLength() throws IOException {
            return responseBody.contentLength();
        }

        @Override public BufferedSource source() throws IOException {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(source(responseBody.source()));
            }
            return bufferedSource;
        }

        private Source source(Source source) {
            return new ForwardingSource(source) {
                long totalBytesRead = 0L;
                @Override public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, byteCount);
                    // read() returns the number of bytes read, or -1 if this source is exhausted.
                    totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                    progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                    return bytesRead;
                }
            };
        }
    }

    private void repeat(){

        Observable.just(url)
                .delay(2, TimeUnit.SECONDS)
                .repeat(5)
                .map(s -> {
                    count++;
                    Log.w(TAG, "数量=" + count);
                    return count + "";
                })
                .filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String s) {

                        return !TextUtils.isEmpty(s);
                    }
                })

                .doOnError(new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {

                    }
                })

                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {

                        Log.i(TAG, "call isMain= " + isMainThread()+" s= "+s);
                        tv.setText(getResources().getString(R.string.hello) + s);
                    }
                });
    }

    @Override
    protected void onStart() {
        super.onStart();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    public void launch_yjb(){

        String url = "http://dldir1.qq.com/dlomg/istock/quanShang/guoJinZhengQuan.apk";

        String packageName = "com.hundsun.stockwinner.zxzq";
        Intent intent = getPackageManager().getLaunchIntentForPackage(packageName);

        if (intent != null) {

            startActivity(intent);
        }else{
            Toast.makeText(this, " no app", Toast.LENGTH_SHORT).show();

            Intent intentView = new Intent(Intent.ACTION_VIEW);
            intentView.setData(Uri.parse(url));
            startActivity(intentView);

        }


        /*try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, 0);

            Intent intent = new Intent();
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            System.out.println("packageName = " + packageName + " / " + packageInfo.packageName);
            intent.setPackage(packageInfo.packageName);

            List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(intent, 0);

            System.out.println("resolveInfos = " + resolveInfos.size());
            ResolveInfo resolveInfo = resolveInfos.iterator().next();

            if(resolveInfo != null){
                String resolvePackageName = resolveInfo.activityInfo.packageName;
                String name = resolveInfo.activityInfo.name;
                Intent intent1 = new Intent();
                intent1.addCategory(Intent.CATEGORY_LAUNCHER);
                ComponentName component = new ComponentName(resolvePackageName, name);
                intent1.setComponent(component);
                startActivity(intent1);

            }


        } catch (Exception e) {
            e.printStackTrace();
        }*/


    }
    /*private void down(String url){



        AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
        asyncHttpClient.get(url, new FileAsyncHttpResponseHandler(this) {
            @Override
            public void onProgress(int bytesWritten, int totalSize) {
                super.onProgress(bytesWritten, totalSize);


            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) {

            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, File file) {

                String absolutePath = file.getAbsolutePath();
                System.out.println("absolutePath = " + absolutePath);
                PackageInfo archiveInfo = getPackageManager().getPackageArchiveInfo(absolutePath, PackageManager.GET_ACTIVITIES);

                String packageName = archiveInfo.packageName;
                System.out.println("packageName = " + packageName);
            }
        });

    }*/
    private void downLoad(String url){

        DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));

        request.setVisibleInDownloadsUi(true);//下载UI是否可见,默认true
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//下载完成后仍可见
        MimeTypeMap singleton = MimeTypeMap.getSingleton();
        request.setMimeType(singleton.getMimeTypeFromExtension("apk"));//根据后缀名来获取mime

        request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, "123.apk");
        MyApplication.downLoadFile = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath() + File.separator + "123.apk";

        downloadManager.enqueue(request);
    }


    private void bianliFile(File file, final String nameFilter){

        FilenameFilter filenameFilter = new FilenameFilter() {
            @Override
            public boolean accept(File dir, String filename) {

                return filename.startsWith(nameFilter);
            }
        };
        File[] files = file.listFiles(filenameFilter);
        for (File file1 : files) {
            if(file1.isDirectory()){
                bianliFile(file1, nameFilter);
            }else{
                String absolutePath = file1.getAbsolutePath();
                System.out.println("absolutePath = " + absolutePath);
            }

        }
    }

    private void retrofitHttp(){

        RestAdapter adapter = new RestAdapter.Builder()
                .setEndpoint("http://api.liangtou.com")
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setLog(new RestAdapter.Log() {
                    @Override
                    public void log(String message) {
                        Log.w(TAG, "message =" + message);
                    }
                })
                .build();

        RetrofitService testService = adapter.create(RetrofitService.class);
        testService.get("retrofit")
                .map(new Func1<HelloObj, HelloObj>() {
                    @Override
                    public HelloObj call(HelloObj helloObj) {
                        Log.w(TAG, "map isMain=" + isMainThread());
                        return helloObj;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<HelloObj>() {
                    @Override
                    public void call(HelloObj helloObj) {

                        Log.w(TAG, "isMain=" + isMainThread());
                        Log.w(TAG, helloObj.toString());
                        tv.setText(helloObj.toString());
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                    }
                });

        /*testService.getResponse("retrofit")
                .subscribe(new Action1<Response>() {
                    @Override
                    public void call(Response response) {

                        try {
                            String s = StreamUtil.readInputStream(response.getBody().in());
                            System.out.println("response = " + s + " url="+response.getUrl() );

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                });*/
    }
    private void span(){
                                 /*SpannableString spannableString = new SpannableString(s);
                                spannableString.setSpan(new ClickableSpan() {
                                    @Override
                                    public void onClick(View widget) {

                                        TextView textView = (TextView) widget;
                                        Log.w(TAG, "click");
                                        Toast.makeText(RxJavaActivity.this, "textView= " + textView.getText(), Toast.LENGTH_SHORT).show();
                                    }
                                }, 3, 6, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
                                spannableString.setSpan(new ClickableSpan() {
                                    @Override
                                    public void onClick(View widget) {

                                        TextView textView = (TextView) widget;
                                        Log.w(TAG, "click");
                                        Toast.makeText(RxJavaActivity.this, "textView= " + textView.getText(), Toast.LENGTH_SHORT).show();
                                    }
                                }, 11, 25, Spanned.SPAN_INCLUSIVE_INCLUSIVE);


                                ClickableSpan clickableSpan = new ClickableSpan() {
                                    @Override
                                    public void onClick(View widget) {

                                    }
                                };
                                SpannableStringBuilder ssb = SpanUtils.setSpanText(s, Pattern.compile("baidu"), new TextColorSpan(Color.RED));

                                tv.setMovementMethod(LinkMovementMethod.getInstance());
                                tv.setText(ssb);

                            }
                        });*/
    }

    private boolean isMainThread() {
        return Looper.myLooper() == Looper.getMainLooper();
    }



    private Observable<String> netWork(String url) {


        return Observable.just(url).map(new Func1<String, String>() {
            @Override
            public String call(String s) {

                return get(s);
            }
        })
                .subscribeOn(Schedulers.io());


    }

    private String get(String url) {

        Log.i(TAG, "net isMain= " + isMainThread());
        final String[] result = new String[1];
        SyncHttpClient syncHttpClient = new SyncHttpClient();

        syncHttpClient.get(url, new TextHttpResponseHandler() {
            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {

            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, String responseString) {

                result[0] = responseString;
            }
        });
        return result[0];

    }

    private void bindActivity(){


    }

}